home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue43 / tooltips / Hints2U.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-01-25  |  3.6 KB  |  136 lines

  1. unit Hints2U;
  2. {$ifdef Ver80} { Delphi 1.0x }
  3.   {$define DelphiLessThan3}
  4. {$endif}
  5. {$ifdef Ver90} { Delphi 2.0x }
  6.   {$define DelphiLessThan3}
  7. {$endif}
  8. {$ifdef Ver93} { C++ Builder 1.0x }
  9.   {$define DelphiLessThan3}
  10. {$endif}
  11.  
  12. interface
  13.  
  14. uses
  15.   WinProcs, WinTypes, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  16.   Dialogs, StdCtrls, Mask, Grids, ExtCtrls;
  17.  
  18. type
  19.   TForm1 = class(TForm)
  20.     SG: TStringGrid;
  21.     Timer1: TTimer;
  22.     procedure FormCreate(Sender: TObject);
  23.     procedure SGMouseMove(Sender: TObject; Shift: TShiftState; X,
  24.       Y: Integer);
  25.     procedure Timer1Timer(Sender: TObject);
  26.   private
  27.     GridHintWnd: THintWindow;
  28.     function CalcHintRect(MaxWidth: Integer;
  29.       const AHint: string; H: THintWindow): TRect;
  30.   public
  31.     { Public declarations }
  32.   end;
  33.  
  34. var
  35.   Form1: TForm1;
  36.  
  37. implementation
  38.  
  39. {$R *.DFM}
  40.  
  41. {$ifdef DelphiLessThan3}
  42. { The private routine Forms.ForegroundTask was only made }
  43. { available in Delphi 3. This is a cheap'n'nasty version of it }
  44. function ForegroundTask: Boolean;
  45. begin
  46.   Result := FindControl(GetActiveWindow) <> nil
  47. end;
  48. {$endif}
  49.  
  50. function TForm1.CalcHintRect(MaxWidth: Integer;
  51.   const AHint: string; H: THintWindow): TRect;
  52. {$ifdef DelphiLessThan3}
  53. var
  54.   Buf: array[0..511] of Char;
  55. begin
  56.   Result := Rect(0, 0, MaxWidth, 0);
  57.   DrawText(H.Canvas.Handle, StrPCopy(Buf, AHint), -1, Result,
  58.     DT_CALCRECT or DT_LEFT or DT_WORDBREAK or DT_NOPREFIX);
  59.   Inc(Result.Right, 6);
  60.   Inc(Result.Bottom, 2);
  61. {$else}
  62. begin
  63.   Result := H.CalcHintRect(Screen.Width, AHint, nil)
  64. {$endif}
  65. end;
  66.  
  67. procedure TForm1.FormCreate(Sender: TObject);
  68. var
  69.   Loop, Loop2: Integer;
  70. begin
  71.   for Loop := 1 to SG.RowCount-1 do
  72.     for Loop2 := 1 to SG.ColCount-1 do
  73.       SG.Cells[Loop2, Loop] := Format('(%d, %d)', [Loop2, Loop]);
  74. end;
  75.  
  76. procedure TForm1.SGMouseMove(Sender: TObject; Shift: TShiftState; X,
  77.   Y: Integer);
  78. const
  79.   TextOffset = 2;
  80. var
  81.   Col, Row: Longint;
  82.   R, OldR: TRect;
  83.   Pt: TPoint;
  84. begin
  85.   { Check cell under mouse }
  86.   SG.MouseToCell(X, Y, Col, Row);
  87.   { If it is a cell, and text is bigger than }
  88.   { screen space and in-place editor not present }
  89.   if (Col <> -1) and (Row <> -1) and
  90.      (SG.Canvas.TextWidth(SG.Cells[Col, Row]) + TextOffset > SG.ColWidths[Col]) and
  91.      not SG.EditorMode and ForegroundTask then
  92.   begin
  93.     { Make sure hint window exists }
  94.     if not Assigned(GridHintWnd) then
  95.     begin
  96.       GridHintWnd := HintWindowClass.Create(Self);
  97.       GridHintWnd.Color := Application.HintColor;
  98.     end;
  99.     { Set hint text }
  100.     SG.Hint := SG.Cells[Col, Row];
  101.     { Calculate rect size }
  102.     R := CalcHintRect(Screen.Width, SG.Hint, GridHintWnd);
  103.     { Find target location }
  104.     Pt := SG.ClientToScreen(SG.CellRect(Col, Row).TopLeft);
  105.     { Tweak position so it is the same as the grid cell (hopefully) }
  106.   {$ifdef DelphiLessThan3}
  107.     Inc(Pt.Y);
  108.   {$else}
  109.     Dec(Pt.X);
  110.     Dec(Pt.Y);
  111.   {$endif}
  112.     OffsetRect(R, Pt.X, Pt.Y);
  113.     { Only draw it if it has moved - compare top-left }
  114.     { (could compare whole rect but the hint sometimes grows itself) }
  115.     GetWindowRect(GridHintWnd.Handle, OldR);
  116.     if not IsWindowVisible(GridHintWnd.Handle) or
  117.        not ((R.Left = OldR.Left) and (R.Top = OldR.Top)) then
  118.       GridHintWnd.ActivateHint(R, SG.Hint)
  119.   end
  120.   else
  121.     if Assigned(GridHintWnd) then
  122.       GridHintWnd.ReleaseHandle
  123. end;
  124.  
  125. procedure TForm1.Timer1Timer(Sender: TObject);
  126. var
  127.   Pt: TPoint;
  128. begin
  129.   GetCursorPos(Pt);
  130.   Pt := ScreenToClient(Pt);
  131.   if not PtInRect(SG.BoundsRect, Pt) and Assigned(GridHintWnd) then
  132.     GridHintWnd.ReleaseHandle
  133. end;
  134.  
  135. end.
  136.